<!--
 * @Author: your name
 * @Date: 2022-11-17 10:53:32
 * @LastEditTime: 2022-12-09 09:49:53
 * @LastEditors: yuhan
 * @Description: 测试api响应速度的抽屉
 * @FilePath: \ft-apiadmin\apiadmin\src\components\CustomTestApiDrawer\index.vue
-->
<template>
  <div class="custom-drawer">
    <el-drawer
      :before-close="handleClose"
      v-model="drawer.visible"
      :close-on-click-modal="false"
      :title="drawer.title"
      direction="rtl"
      size="1100px"
    >
      <el-card class="box-card bottom-in" style="width: 350px">
        <template #header>
          <div class="card-header">
            待测api列表
            <el-button
              class="button"
              plain
              type="primary"
              size="small"
              @click="handleEdit('refresh')"
              :icon="Refresh"
              >重新测试</el-button
            >
          </div>
        </template>
        <div class="contentBox">
          <el-table :data="drawer.apiList" style="width: 100%">
            <el-table-column prop="id" label="ID" align="center" width="50px" />
            <el-table-column prop="name" label="API名称" align="center" />
            <el-table-column label="操作" align="center" width="80px">
              <template #default="scope">
                <el-button
                  type="danger"
                  size="small"
                  @click="handleEdit('deleteTestApi', scope.row)"
                >
                  删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-card>
      <el-card class="box-card resultBox bottom-in" style="width: 700px" v-loading="drawer.loading">
        <template #header>
          <div class="card-header">
            结果展示表
            <el-button
              class="button"
              plain
              size="small"
              @click="handleEdit('creatApi')"
              :icon="Delete"
              >清空</el-button
            >
          </div>
        </template>
        <div class="contentBox">
          <el-table :data="drawer.responeDataList" style="width: 100%">
            <el-table-column type="expand" width="25px">
              <template #default="props">
                <!-- {{ props.row }} -->
                <el-descriptions title="详情描述">
                  <el-descriptions-item label="ID">{{ props.row.apiId }}</el-descriptions-item>
                  <el-descriptions-item label="API名称">{{
                    props.row.apiName
                  }}</el-descriptions-item>
                  <el-descriptions-item label="请求结果">
                    <el-tag class="ml-2" :type="props.row.success ? 'success' : 'danger'">{{
                      props.row.success ? "成功" : "失败"
                    }}</el-tag>
                  </el-descriptions-item>
                  <el-descriptions-item label="总耗时"
                    >{{ props.row.allTestTime }}ms</el-descriptions-item
                  >
                  <el-descriptions-item label="第三方耗时"
                    >{{ props.row.thirdTime }}ms</el-descriptions-item
                  >
                  <el-descriptions-item label="其他耗时"
                    >{{ props.row.otherTime }}ms</el-descriptions-item
                  >
                  <el-descriptions-item label-class-name="hiddenDsLabel" label="" :span="3"
                    ><Echarts
                      :index="2"
                      title="耗时统计图表"
                      headerIcon="icon-chart-histogram"
                      :style="{
                        height: '120px',
                      }"
                      :options="{
                        tooltip: {
                          trigger: 'item',
                        },
                        series: [
                          {
                            name: '耗时',
                            type: 'pie',
                            radius: ['70%', '90%'],
                            avoidLabelOverlap: false,
                            itemStyle: {
                              borderRadius: 10,
                              borderColor: 'rgba(255, 255, 255, 0)',
                              borderWidth: 2,
                            },
                            label: {
                              show: false,
                              position: 'center',
                            },
                            emphasis: {
                              label: {
                                show: true,
                                fontSize: '14',
                              },
                            },
                            labelLine: {
                              show: false,
                            },
                            data: [
                              { value: props.row.thirdTime, name: '第三方耗时' },
                              { value: props.row.otherTime, name: '其他耗时' },
                            ],
                          },
                        ],
                      }"
                  /></el-descriptions-item>
                  <el-descriptions-item label="报文对比" :span="3">
                    <div class="testCompare">
                      <div class="compareBox">
                        <p class="title">原始报文</p>
                        <json-viewer
                          v-if="props.row.result.data"
                          :value="props.row.result.data"
                          :expand-depth="5"
                          copyable
                          boxed
                          :show-array-index="false"
                          sort
                        ></json-viewer>
                        <span v-else>-</span>
                      </div>
                      <div class="compareBox">
                        <p class="title">处理后报文</p>
                        <json-viewer
                          v-if="props.row.result.cleanData"
                          :value="props.row.result.cleanData"
                          :expand-depth="5"
                          copyable
                          boxed
                          :show-array-index="false"
                          sort
                        ></json-viewer>
                        <span v-else>-</span>
                      </div>
                    </div>
                  </el-descriptions-item>
                  <!-- <el-descriptions-item label="原始报文" :span="1.5">{{
                    props.row.result.data || ''
                  }}</el-descriptions-item>
                  <el-descriptions-item label="处理后报文" :span="1.5">{{
                    props.row.result.cleanData || ''
                  }}</el-descriptions-item> -->
                </el-descriptions>
              </template></el-table-column
            >
            <el-table-column prop="apiId" label="ID" align="center" width="50px" />
            <el-table-column prop="apiName" label="API名称" align="center" min-width="70px" />
            <el-table-column prop="apiName" label="请求结果" align="center" min-width="50px">
              <template #default="scope">
                <el-tag class="ml-2" :type="scope.row.success ? 'success' : 'danger'">{{
                  scope.row.success ? "成功" : "失败"
                }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="allTestTime" label="总耗时" align="center" min-width="50px">
              <template #default="scope"> {{ scope.row.allTestTime }}ms </template>
            </el-table-column>
            <el-table-column prop="thirdTime" label="第三方耗时" align="center" min-width="60px">
              <template #default="scope"> {{ scope.row.thirdTime }}ms </template>
            </el-table-column>
            <el-table-column prop="otherTime" label="其他耗时" align="center" min-width="50px">
              <template #default="scope"> {{ scope.row.otherTime }}ms </template>
            </el-table-column>
          </el-table>
        </div>
      </el-card>
    </el-drawer>
  </div>
</template>
<script setup>
import { ref, defineProps, watch, defineEmits } from "vue";
import { Delete, Refresh } from "@element-plus/icons-vue";
import apiUrl from "@/config/api.mjs";
import request from "@/utils/request";
import { useI18n } from "vue-i18n";
import JsonViewer from "vue-json-viewer";
const props = defineProps({
  title: {
    type: String,
    default: "",
  },
  visible: {
    type: Boolean,
    default: false,
  },
  testApiList: {
    type: Array,
    default: () => [],
  },
});
const emits = defineEmits(["closecb"]);
const drawer = ref({
  loading: false,
  visible: false,
  title: "",
  apiList: [], // 要测速的api id
  responeDataList: [],
});
// 调用测试接口
const testApi = async (api) => {
  let startTime = new Date().getTime();
  let endTime = 0;
  await request({
    url: `${apiUrl.testApiResponeSpeed}`,
    method: "post",
    data: {
      id: api.id,
    },
  })
    .then((res) => {
      endTime = new Date().getTime();
      // console.log('总耗时', endTime - startTime);
      // console.log('第三方耗时', res.result.time);
      // console.log('其他耗时', endTime - startTime - res.result.time);
      if (res.result) {
        drawer.value.responeDataList.push({
          apiId: api.id,
          apiName: api.name,
          allTestTime: endTime - startTime, // 总耗时
          thirdTime: res.result.time, // 第三方耗时
          otherTime: endTime - startTime - res.result.time, // 其他耗时
          success: true,
          result: res.result,
        });
      } else {
        drawer.value.responeDataList.push({
          apiId: api.id,
          apiName: api.name,
          allTestTime: endTime - startTime, // 总耗时
          thirdTime: 0, // 第三方耗时
          otherTime: endTime - startTime, // 其他耗时
          success: false,
          result: {},
        });
      }
    })
    .finally(() => {});
};
// 多个调用入口
const multipleTest = async () => {
  drawer.value.loading = true;
  for (let i = 0; i <= drawer.value.apiList.length - 1; i++) {
    await testApi(drawer.value.apiList[i]);
  }

  drawer.value.loading = false;
};
watch(
  props,
  (nv) => {
    if (nv) {
      const initData = JSON.parse(JSON.stringify(nv));
      drawer.value.title = initData.title || "";
      drawer.value.visible = initData.visible || false;
      drawer.value.apiList = initData.testApiList || [];
      drawer.value.responeDataList = [];
      if (drawer.value.visible) {
        multipleTest();
      }
    }
  },
  {
    immediate: true,
    deep: true,
  }
);
// 操作统一入口
const handleEdit = (editType, row) => {
  switch (editType) {
    case "refresh":
      drawer.value.responeDataList = [];
      multipleTest();
      break;
    case "creatApi":
      drawer.value.responeDataList = [];
      break;
    case "deleteTestApi":
      deleteTestApi(row);
      break;
    default:
      break;
  }
};
// 删除测试api
const deleteTestApi = (row) => {
  let targetIndex = drawer.value.apiList.findIndex((item) => item.id === row.id);
  if (targetIndex !== -1) {
    drawer.value.apiList.splice(targetIndex, 1);
  }
};
// 关闭抽屉
const handleClose = (done) => {
  drawer.value.apiList = [];
  drawer.value.responeDataList = [];
  emits("closecb", false);
};
</script>
<style lang="scss" scoped>
.custom-drawer {
  :deep(.el-drawer__header) {
    margin-bottom: 5px;
  }
  :deep(.el-drawer__body) {
    display: flex;
    justify-content: space-between;
  }
  .box-card {
    margin-bottom: 10px;
    // margin-right: 10px;
    .card-header {
      display: flex;
      justify-content: space-between;
    }
    :deep(.el-card__body) {
      height: calc(100% - 100px);
      .contentBox {
        // max-height: 350px !important;
        height: 100%;
        overflow: auto;
        .el-table__cell {
          .el-descriptions {
            padding-right: 10px;
            .el-descriptions__label {
              font-weight: bold;
            }
            .hiddenDsLabel {
              display: none;
            }
          }
          .echart-card {
            // width: 300px;
            .el-card__header {
              padding: 5px;
            }
          }
        }
      }
    }
  }
  .testCompare {
    display: flex;
    .compareBox {
      width: 50%;
      .title {
        // font-size: 14px;
        color: #606266;
        // font-weight: bold;
        text-align: center;
      }
    }
  }
}
</style>
